﻿using System;
using System.Windows.Input;
using WinRTFramework.Common;
using WinRTFramework.FrameworkConfiguration;
using WinRTFramework.Interfaces.Navigation;
using Windows.UI.Xaml.Controls;

namespace WinRTFramework.FrameworkCore.Services
{
    internal class NavigationService : INavigationService
    {
        private readonly Frame _rootFrame;
        IViewViewModelMapper _viewProvider;

        public NavigationService(Frame rootFrame, IViewViewModelMapper viewProvider)
        {
            _rootFrame = rootFrame;
            _viewProvider = viewProvider;
        }

        private DelegateCommand _goBackCommand;
        public ICommand GoBackCommand
        {
            get { return _goBackCommand = _goBackCommand ?? new DelegateCommand(GoBack, () => CanGoBack); }
        }

        private DelegateCommand _goForwardCommand;
        public ICommand GoForwardCommand
        {
            get { return _goForwardCommand = _goForwardCommand ?? new DelegateCommand(GoForward, () => CanGoForward); }
        }

        private DelegateCommand _goHomeCommand;
        public ICommand GoHomeCommand
        {
            get { return _goHomeCommand = _goHomeCommand ?? new DelegateCommand(GoHome, () => CanGoHome); }
        }

        public bool CanGoBack
        {
            get { return _rootFrame.CanGoBack; }
        }

        public void GoBack()
        {
            _rootFrame.GoBack();
        }

        public bool CanGoForward
        {
            get { return _rootFrame.CanGoForward; }
        }

        public void GoForward()
        {
            _rootFrame.GoForward();
        }

        public bool CanGoHome
        {
            get { return CanGoBack; }
        }

        public void GoHome()
        {
            while(_rootFrame.CanGoBack)
                _rootFrame.GoBack();
        }

        public bool Navigate<TViewModelType>()
        {
            return Navigate<TViewModelType>(null);
        }

        public bool Navigate<TViewModelType>(object navigationParameter)
        {
            return Navigate(typeof (TViewModelType), navigationParameter);
        }

        public bool Navigate(Type vmType)
        {
            return Navigate(vmType, null);
        }

        public bool Navigate(Type vmType, object navigationParameter)
        {
            var viewType = _viewProvider.GetViewTypeForViewModelType(vmType, navigationParameter);
            return Navigate(viewType, navigationParameter, vmType);
        }

        private bool Navigate(Type pageType, object navigationParameter, Type viewModelType)
        {
            return _rootFrame.Navigate(pageType, navigationParameter);
        }
    }
}
